/*
 * fileName: CreateEntity.java
 * author: ewangshi
 * createDate: 2013-8-8
 */
package com.ws.base.common.entity;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.ws.base.common.WSAppLogger;

/**
 * @author ewangshi
 * 
 */
public final class CreateEntity {

    private WSAppLogger log = WSAppLogger.getWSAppLogger(CreateEntity.class);

    private static final String SET_MENTHOD_PREFIX = "set";

    private CreateEntity() {
    }

    private static class SingletonHolder {
        private final static CreateEntity INSTANCE = new CreateEntity();
    }

    public static CreateEntity getInstance() {
        return SingletonHolder.INSTANCE;
    }

    public final <T> T map2Obj(Map<String, Object> map, Class<T> clazz) {
        Method[] methods = clazz.getMethods();
        T t = null;

        try {

            t = clazz.newInstance();

            for (Method method : methods) {
                if (method.getName().startsWith(SET_MENTHOD_PREFIX)
                        && method.getName().length() > 3) {
                    String _field = getFieldByMethodName(method.getName());
                    if (map.containsKey(_field)) {
                        setMethodHandle(t, method, map.get(_field));
                    }
                }
            }

        } catch (InstantiationException e) {
            log.error(e);
        } catch (IllegalAccessException e) {
            log.error(e);
        } catch (IllegalArgumentException e) {
            log.error(e);
        } catch (InvocationTargetException e) {
            log.error(e);
        }

        return t;
    }

    public <T> List<T> map2ListObj(List<Map<String, Object>> list,
            Class<T> clazz) {
        List<T> tList = new ArrayList<T>();

        for (Map<String, Object> map : list) {
            tList.add(map2Obj(map, clazz));
        }
        return tList;
    }

    private String getFieldByMethodName(String methodName) {
        int size = methodName.length();
        String prefix = methodName.substring(3, 4);
        if (size > 4) {
            prefix += methodName.substring(4, size);
        }
        return prefix.toLowerCase();
    }

    private <T> void setMethodHandle(T t, Method method, Object fieldVal)
            throws IllegalArgumentException, IllegalAccessException,
            InvocationTargetException {
        Class<?>[] types = method.getParameterTypes();

        if (types.length == 1) {
            method.invoke(t, fieldVal);
        }
    }

}
